/*************************************************************************
 *
 *  Copyright (C) 2013 Florian Dang <florian.coin@gmail.com>
 *
 *  This file is part of NatusVerse.
 *
 *  NatusVerse is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  NatusVerse is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with NatusVerse.  If not, see <http://www.gnu.org/licenses/>.
 *
 *************************************************************************/

#include "graphics/graphics.h"
using graphics::Graphics;
using color::t_color;

#include <cmath>
#include <cassert>

namespace graphics
{
typedef Graphics::t_point t_point;
typedef Graphics::t_vector t_vector;

const t_point  Graphics::kpoint_orig_t = {0, 0};
const t_vector Graphics::kforce_orig_t = {0, 0};

void Graphics::InitGraphics()
{
	if (SDL_screen_ == NULL)
	{
		fprintf(stderr, "(!!!) Cannot %dx%d in 32 bits: %s\n",
				w_, h_, SDL_GetError());
		exit(1);
	}

	w_  = SDL_screen_->w;
	h_ = SDL_screen_->h;

	if (show_cursor_ == true)
		SDL_ShowCursor(SDL_ENABLE);
	else
		SDL_ShowCursor(SDL_DISABLE);

	printf("(i) Resolution:%dx%d | Cursor:%d\n", w_, h_, show_cursor_);

	// Long press key enabled
	SDL_EnableKeyRepeat(1, 0);

	SDL_WM_SetCaption("NatusVerse", NULL);

	FillScreen(color::black);

	PrintScreen();
}

void Graphics::PrintScreen()
{
	SDL_Event event;
	if (SDL_PollEvent(&event))
		if (event.type == SDL_QUIT)
			exit(0);

	SDL_Flip(SDL_screen_);
}

void Graphics::FillScreen(t_color color)
{
	for (int i = 0; i < w_; i ++)
		for (int j = 0; j < h_; j ++)
			*(reinterpret_cast<t_color *> (SDL_screen_->pixels) + \
				(h_-j-1) * w_ + i) = color;


	if (autoprint_)
		PrintScreen();
}

void Graphics::AddPix(int x, int y, t_color color)
{
	/* METHOD 1 */
	// if ((x => 0 && x < w_ && y > 0 && y < h_) == false)
	// {
	// 	printf("x=%d y=%d w_=%d h_=%d,\n",x,y, w_, h_);
	// 	printf("%d ", x=>0); printf("%d ", x < w_); printf("%d ", y > 0); printf("%d\n ", y < h_);
	// }

	//if (x <= 0 || x > w_ || y <= 0 || y > h_)
	// assert(x >= 0 && x < w_ && y > 0 && y < h_);
	if(x >= 0 && x < w_ && y > 0 && y < h_)
		*(reinterpret_cast<t_color *> (SDL_screen_->pixels) + \
			(h_ - y - 1) * w_ + x) = color;

	/* METHOD 2 (axis inverted)*/
/*
    int bpp = SDL_screen_->format->BytesPerPixel;
    // Here p is the address to the pixel we want to set
    Uint8 *p = (Uint8 *)SDL_screen_->pixels + y * SDL_screen_->pitch + x * bpp;

    switch(bpp) {
    case 1:
        *p = color;
        break;

    case 2:
        *(Uint16 *)p = color;
        break;

    case 3:
        if(SDL_BYTEORDER == SDL_BIG_ENDIAN) {
            p[0] = (color >> 16) & 0xff;
            p[1] = (color >> 8) & 0xff;
            p[2] = color & 0xff;
        } else {
            p[0] = color & 0xff;
            p[1] = (color >> 8) & 0xff;
            p[2] = (color >> 16) & 0xff;
        }
        break;

    case 4:
        *(Uint32 *)p = color;
        break;
    }
 */
}

void Graphics::PrintImg(char *filename, t_point bg, int w, int h)
{
	SDL_Surface *image = NULL;
	SDL_Rect rect;

	rect.x = bg.x;
	rect.y = h_ - bg.y;
	rect.w = w;
	rect.h = h;
	image = SDL_LoadBMP(filename);

	if (image == NULL)
		fprintf(stderr, "Cannot load %s", filename);

	/* On blitte par-dessus l'écran */
	SDL_BlitSurface(image, NULL, SDL_screen_, &rect);
	if (autoprint_)
		PrintScreen();
}


t_point Graphics::WaitClic()
{
	int no_quit_event = 1;
	SDL_Event event;
	t_point P;
	P.x = 0;
	P.y = 0;

	while (SDL_WaitEvent(&event) && no_quit_event)
	{
		/* Si l'utilisateur clique avec la souris */
		if ((event.type == SDL_MOUSEBUTTONDOWN) &&
			(event.button.button == SDL_BUTTON_LEFT))
		{
			no_quit_event = 0;
			P.x = event.button.x;
			P.y = h_-event.button.y;
		}
		/* Si l'utilisateur déplace la souris */
		if (event.type == SDL_MOUSEMOTION)
		{
			printf("%cWaiting clic... %4d %4d\t%c",
					13, event.motion.x, h_ - event.motion.y, 13);
			fflush(stdout);
		}

		if (event.type == SDL_QUIT)
			exit(0);
	}
	printf("%cClic at %4f %4f\n", 13, P.x, P.y);
	mousepos_ = P;

	return P;
}

void Graphics::WaitEscape()
{

	int display = 1;
	SDL_Event event;

	std::string txt = ">> Press Escape";
	printf("%s\n", txt.c_str());

	PrintScreen();

	while (SDL_WaitEvent(&event) && display)
	{
		if (event.type == SDL_QUIT)
			exit(0);

		if (event.type == SDL_KEYDOWN)
		{
			switch (event.key.keysym.sym)
			{
				case SDLK_ESCAPE :
				{
					display = 0;
					break;
				}
				default :
					break;
			}
		}
	}

	SDL_Quit();
}

void Graphics::Quit()
{
	SDL_Quit();
}

} // end namespace
